﻿namespace App.Web
{
    using System;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Microsoft.Practices.Unity;

    public class CustomControllerFactory : IControllerFactory
    {
        private IUnityContainer container;
        private IControllerFactory innerFactory;

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomServiceLocator"/> class.
        /// </summary>
        /// <param name="container">The container.</param>
        public CustomControllerFactory(IUnityContainer container)
            : this(container, new DefaultControllerFactory())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomControllerFactory"/> class.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="innerFactory">The inner factory.</param>
        protected CustomControllerFactory(IUnityContainer container, IControllerFactory innerFactory) {
            this.container = container;
            this.innerFactory = innerFactory;
        }

        /// <summary>
        /// Creates the specified controller by using the specified request context.
        /// </summary>
        /// <param name="requestContext">The request context.</param>
        /// <param name="controllerName">The name of the controller.</param>
        /// <returns>The controller.</returns>
        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            try
            {
                return container.Resolve<IController>(controllerName.ToLowerInvariant());
            }
            catch (Exception)
            {
                return innerFactory.CreateController(requestContext, controllerName);
            }
        }

        /// <summary>
        /// Releases the specified controller.
        /// </summary>
        /// <param name="controller">The controller.</param>
        public void ReleaseController(IController controller)
        {
            container.Teardown(controller);
        }
    }
}
